#include "d3dApp.h"
#include "Terrain.h"
#include "Lighting.h"
#include "Waves.h"
#include "Effects.h"
#include "InputLayouts.h"
#include "TextureMgr.h"
#include "Sky.h"
#include "Camera.h"



class TerrainApp : public D3DApp 
{
private:
	// Wave
	Waves   mWaves;
	// lights
	Light	mParallelLight;
	// sky
	Sky		mSky;
	// land
	Terrain mTerrain;

	// mouse
	bool	mLeftMouseUp;

	ID3D10ShaderResourceView		*mDefaultSpecMapRV;
	ID3D10ShaderResourceView		*mEnvMapRV;

	ID3D10EffectTechnique			*mTech;
	ID3D10EffectMatrixVariable		*mfxWVPVar;
	ID3D10EffectMatrixVariable		*mfxWorldVar;
	ID3D10EffectMatrixVariable		*mfxTexMtxVar;
	ID3D10EffectVectorVariable		*mfxReflectMtrlVar;
	ID3D10EffectScalarVariable		*mfxCubeMapEnabledVar;
	ID3D10EffectVariable			*mfxEyePosVar;
	ID3D10EffectVariable			*mfxLightVar;
	ID3D10EffectShaderResourceVariable	*mfxDiffuseMapVar;
	ID3D10EffectShaderResourceVariable	*mfxSpecMapVar;
	ID3D10EffectShaderResourceVariable	*mfxCubeMapVar;

	// view pos and dir
	POINT	mInitCursorPos;
	POINT	mPrevCursorPos;

	D3DXVECTOR4 mReflectNone;
	D3DXVECTOR4 mReflectAll;
	D3DXVECTOR4 mReflectSoso;

public:
	TerrainApp(HINSTANCE hInstance) 
		: D3DApp(hInstance), mfxDiffuseMapVar(0), mDefaultSpecMapRV(0), mEnvMapRV(0),
		mLeftMouseUp(false)
	{
		mClientWidth    = 512;
		mClientHeight   = 384;

		mReflectNone = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 1.0f);
		mReflectAll  = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);
		mReflectSoso  = D3DXVECTOR4(0.4f, 0.4f, 0.4f, 1.0f);
	}

	virtual ~TerrainApp() {
		if( md3dDevice )
			md3dDevice->ClearState();

		fx::DestroyAll();
		InputLayout::DestroyAll();
	}

	void initApp();
	void onResize();
	void updateScene(float dt);
	void drawScene();
	virtual LRESULT msgProc(UINT msg, WPARAM wParam, LPARAM lParam);

	static const D3DXVECTOR3 UP;
	static const float PIOVER2;
	static const float PI2;

private:
	void buildLights();
	void initResources();
	void updatePosition(float dt);
	void updateDirection(float dt);
	void interactAtSea();
};
